package top.huxy.boot.controller.all;

import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import top.huxy.boot.exception.RequestAbortedException;
import top.huxy.boot.model.dto.Query;
import top.huxy.boot.util.obj.BinaryResult;
import top.huxy.boot.util.obj.Result;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

@RestController
@RequestMapping("/util")
@Slf4j
public class UtilController {

    @GetMapping("/getAvailableImgConvertType")
    public Result getAvailableImgConvertType() {
        return Result.success(ImageIO.getWriterFormatNames());
    }

    @PostMapping(value = "/covertImg")
    public BinaryResult covertImg(Query query, MultipartFile file, HttpServletResponse response) throws IOException {

        Map<String, Object> queryMap = query
                .allowKey("fmt", false)
                .defaultValue("fmt", "jpg")

                .allowKey("quality", false)
                .replaceValue("quality", s -> {
                    int i = Integer.parseInt(s);
                    if (i > 1000) {
                        i = 1000;
                    } else if (i < 1) {
                        i = 1;
                    }
                    return i;
                })
                .defaultValue("quality", 100)

                .allowKey("scale", false)
                .replaceValue("scale", Integer::parseInt)
                .defaultValue("scale", 100)

                .getQueryMap();
        String fmt = queryMap.get("fmt").toString();
        if (!canConvert(fmt)) {
            throw new RequestAbortedException("无法转换的类型:" + fmt);
        }
        Thumbnails.Builder<? extends InputStream> builder = Thumbnails.of(file.getInputStream());
        try {
            builder.outputFormat(fmt);
            builder.outputQuality(Integer.parseInt(queryMap.get("quality").toString()) * 1.0 / 100);
            builder.scale(Integer.parseInt(queryMap.get("scale").toString()) * 1.0 / 100);
            if ("png".equalsIgnoreCase(fmt)) {
                response.setContentType(MediaType.IMAGE_PNG_VALUE);
            } else {
                response.setContentType(MediaType.IMAGE_JPEG_VALUE);
            }
            BufferedImage image = builder.asBufferedImage();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ImageIO.write(image, fmt, out);
            byte[] bytes = out.toByteArray();
            return BinaryResult.send(bytes, Result.success("转换成功"));
        } catch (Exception e) {
            response.setContentType(file.getContentType());
            byte[] bytes = file.getBytes();
            return BinaryResult.send(bytes, Result.clientError("转换失败",e.getMessage()));
        }
    }

    private boolean canConvert(String fmt) {
        if (fmt == null) {
            return false;
        }
        String[] writerFormatNames = ImageIO.getWriterFormatNames();
        for (String s : writerFormatNames) {
            if (fmt.equalsIgnoreCase(s)) {
                return true;
            }
        }
        return false;
    }
}
